#include<iostream>
#include<list>
#include<map>
#include<set>
using namespace std;

#define forn(i,n) for(int i=0;i<(n);i++)
#define forsn(i,s,n) for(int i=(s);i<(n);i++)
#define forall(it,X) for(typeof((X).begin()) it=(X).begin();it!=(X).end();it++)

/*#define TIEMPO*/

void imprimir(bool* clausulas, const bool* variables, int c, int v, list<int>& tautologias){
	forall(t, tautologias) clausulas[*t]=true;
	/* Cantidad de clausulas satisfechas */

	int n = 0;
	forn(i,c) if(clausulas[i]) n++;
	cout << n << endl;

	/* Clausulas satisfechas */

	cout << "C";
	forn(i,c) if(clausulas[i]) cout << " " << i+1;
	cout << endl;

	/* Variables verdaderas */

	cout << "V";
	forn(i,v) if(variables[i]) cout << " " << i+1;
	cout << endl;
}

int clausulas_sat(map<int,list<int> > var, bool*clausulas,const bool*variables, int c, int v){
	forn(i,c) clausulas[i] = false;
	forn(i,v)
		if(variables[i]==true) forall(it,var[i+1]) clausulas[*it] = true;
		else forall(it,var[-i-1]) clausulas[*it] = true;
	int cs = 0; forn(i,c) if(clausulas[i]) cs++;
	return cs;
}

int sat(int va, map<int,list<int> >&var, bool*clausulas){
	int c=0;
	forall(it,var[va]) c+=!clausulas[*it];
	return c;
}

int main(){
	int c; int v;

#ifdef TIEMPO
	int caso = 1;
#endif

	while( cin >> c && cin >> v && c!=-1 && v!=-1 ){

		map<int,list<int> > var;
		bool variables[v]; forn(i,v) variables[i] = true;
		bool clausulas[c]; forn(i,c) clausulas[i] = false;
		list<int> tautologias; //tautologias que leo en la entrada, hay que imprimirlas como satisfechas..

		/* Leo la entrada. Guardo para cada variable,
		 * la lista de clausulas a la que pertenece.
		 * Las variables estan organizadas en un arreglo */

		forn(i,c){
			set<int> clausula;
			bool tautologia = false;
			int j; cin >> j;
			forn(l,j){
				int va; cin >> va;
				/* chequeo si es una tautologia */
				if(clausula.count(-va)) tautologia = true;
				clausula.insert(va);
				//var[va].push_back( i );
			}
			if(!tautologia) forall(it,clausula) var[*it].push_back(i);
			else tautologias.push_back(i);
		}

		/* Algoritmo constructivo */

		forsn(va,1,v+1){
			bool val = variables[va-1] = sat(va,var,clausulas) > sat(-va,var,clausulas);
			forall(it,var[va*(val?1:-1)]) clausulas[*it]=true;
		}

		/* Algoritmo */

#ifdef TIEMPO
		clock_t t = clock();
#endif

		bool max = false;
		int max_cs = clausulas_sat(var, clausulas, variables, c, v);
		int var_max;

		while(!max){

			max = true;

			/* Por cada una de las variables */
			forn(i,v){

				/* Pruebo invertir el valor de la variable */
				variables[i] = !variables[i]; 

				/* Devuelve el numero de clausulas saturadas
				 * para un conjunto de variables */
				int cs = clausulas_sat(var, clausulas, variables, c, v);

				if(cs > max_cs){

					/* Si encontre un conjunto de mayor clausulas saturadas
				 	* para este conjunto de variables verdaderas,
				 	* paso a probar soluciones locales para esta nueva configuracion */

				 	max_cs = cs;
					max = false;
					var_max=i;
					//break;

				}//else{

					/* Si no es mejor, me quedo con
					 * el conjunto de variables original */

					variables[i] = !variables[i];

				//}
			}
			if(!max) variables[var_max] = !variables[var_max];
		}

#ifdef TIEMPO

		t = clock() - t;

		cout << "caso: " << caso << endl;
		clog << 1000*(float)t/CLOCKS_PER_SEC << endl;

		caso++;
#endif
#ifndef TIEMPO
		/* Imprimo el resultado final
		 * en el formato requerido */
		imprimir(clausulas,variables,c,v,tautologias);
#endif
	}
	return 0;
}
